package calao.storage;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import calao.util.Cursor;

public class DumpOutputStream 
extends DataOutputStream
{

	class DumpDataWriter extends DataWriter {
		public void write(int value) {
			try {
				writeInt(value);
			} 
			catch (IOException e) { 
				throw new RuntimeException(e);
			}
		}
		public void write(long value) {
			try {
				writeLong(value);
			} 
			catch (IOException e) { 
				throw new RuntimeException(e);
			}
		}
		public void write(double value) {
			try {
				writeDouble(value);
			} 
			catch (IOException e) { 
				throw new RuntimeException(e);
			}
		}
		public void write(String value) {
			try {
				writeUTF(value);
			} 
			catch (IOException e) { 
				throw new RuntimeException(e);
			}
		}
		public void write(boolean value) {
			try {
				writeBoolean(value);
			} 
			catch (IOException e) { 
				throw new RuntimeException(e);
			}
		}
	}
	
	public DumpOutputStream(OutputStream stream) 
	{
		super(stream);
	}
	
	public void dump(Storage storage) 
	throws IOException
	{
		for (Table table : storage.getTables()) {
			write(1);
			writeUTF(table.getName());
			Cursor<Record> cursor = storage.list(table);
			while (cursor.next()) {
				write(1);
				dump(cursor.get());
			}
			cursor.close();
			write(0);
		}
		for (Sequence seq : Sequence.MAP.values()) {
			write(2);
			writeUTF(seq.name);
			writeInt(storage.getValue(seq));
		}
		write(0);
	}
	
	void dump(Record record)
	throws IOException
	{
		for (Field field : record.table.getFieldList()) {
			write(1);
			writeUTF(field.getName());
			Object[] values = record.directGetAll(field);
			write(values.length);
			for (Object value : values) {
				switch (field.type.enumValue) {
				case INTEGER:
					writeInt((Integer)value);
					break;
				case SHORT:
					writeShort((Short)value);
					break;
				case LONG:
					writeLong((Long)value);
					break;
				case DOUBLE:
					writeDouble((Double)value);
					break;
				case STRING:
					writeUTF((String)value);
					break;
				case OBJECT:
					DumpDataWriter writer = new DumpDataWriter();
					writer.write(value);
					break;			
				}
			}
		}
		write(0);
	}

}
